package com.wzb.mybatisplus.bitaction.electrumaction;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class ElectrumSSLClient {

    private static final String ELECTRUM_SERVER_HOST = "electrum.bitaroo.net";
    private static final int ELECTRUM_SSL_PORT = 50002;

    private SSLSocket socket;
    private BufferedReader reader;
    private BufferedWriter writer;
    private ObjectMapper mapper;
    private int requestId = 0;

    public static void main(String[] args) {
        ElectrumSSLClient client = new ElectrumSSLClient();

        try {
            System.out.println("=== Electrum SSL 客户端 ===\n");

            // 方法1: 使用自定义信任管理器
            if (client.connectWithCustomSSL()) {
                client.testConnection();
                client.disconnect();
            }

            System.out.println("\n--- 尝试方法2 ---");

            // 方法2: 使用系统信任库
//            if (client.connectWithSystemSSL()) {
//                client.testConnection();
//                client.disconnect();
//            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法1: 使用自定义SSL上下文
     */
    public boolean connectWithCustomSSL() {
        try {
            System.out.println("方法1: 使用自定义SSL上下文");

            // 创建自定义信任管理器
            TrustManager[] trustAllCerts = createTrustManager();

            // 创建SSL上下文
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new SecureRandom());

            // 创建Socket工厂
            SSLSocketFactory socketFactory = sslContext.getSocketFactory();

            // 建立连接
            socket = (SSLSocket) socketFactory.createSocket(ELECTRUM_SERVER_HOST, ELECTRUM_SSL_PORT);
            configureSocket();

            System.out.println("✓ SSL连接建立成功");
            return true;

        } catch (Exception e) {
            System.err.println("✗ SSL连接失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 方法2: 使用系统默认SSL上下文
     */
    public boolean connectWithSystemSSL() {
        try {
            System.out.println("方法2: 使用系统默认SSL");

            SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            socket = (SSLSocket) socketFactory.createSocket(ELECTRUM_SERVER_HOST, ELECTRUM_SSL_PORT);
            configureSocket();

            System.out.println("✓ 系统SSL连接建立成功");
            return true;

        } catch (Exception e) {
            System.err.println("✗ 系统SSL连接失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 配置Socket参数
     */
    private void configureSocket() throws IOException {
        // 启用TLS协议
        socket.setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.3"});

        // 启用密码套件
        socket.setEnabledCipherSuites(new String[]{
                "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
                "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
                "TLS_RSA_WITH_AES_128_GCM_SHA256"
        });

        socket.setSoTimeout(30000);
        socket.startHandshake(); // 显式开始SSL握手

        // 创建读写流
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        mapper = new ObjectMapper();
    }

    /**
     * 创建信任所有证书的TrustManager
     */
    private TrustManager[] createTrustManager() {
        return new TrustManager[] {
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType)
                            throws CertificateException {
                        // 信任所有客户端证书
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType)
                            throws CertificateException {
                        // 信任所有服务器证书
                        System.out.println("信任服务器证书: " +
                                (chain.length > 0 ? chain[0].getSubjectX500Principal() : "未知"));
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0]; // 返回空数组
                    }
                }
        };
    }

    /**
     * 测试连接
     */
    public void testConnection() {
        try {
            // 1. 服务器版本查询
            String version = getServerVersion();
            System.out.println("服务器版本: " + version);

            // 2. 服务器横幅
            String banner = getServerBanner();
            System.out.println("服务器横幅: " + banner);

            // 3. Ping测试
            String pingResult = pingServer();
            System.out.println("Ping结果: " + pingResult);

        } catch (Exception e) {
            System.err.println("测试连接失败: " + e.getMessage());
        }
    }

    /**
     * 获取服务器版本
     */
    public String getServerVersion() {
        try {
            String response = sendRequest("server.version",
                    mapper.createArrayNode()
                            .add("java-electrum-ssl-client")
                            .add("1.4.2"));

            if (response != null) {
                JsonNode root = mapper.readTree(response);
                JsonNode result = root.get("result");
                if (result != null && result.isArray() && result.size() > 0) {
                    return result.get(0).asText();
                }
            }
            return "获取失败";
        } catch (Exception e) {
            return "异常: " + e.getMessage();
        }
    }

    /**
     * 获取服务器横幅
     */
    public String getServerBanner() {
        try {
            String response = sendRequest("server.banner", mapper.createArrayNode());
            if (response != null) {
                JsonNode root = mapper.readTree(response);
                JsonNode result = root.get("result");
                if (result != null) {
                    return result.asText();
                }
            }
            return "无横幅";
        } catch (Exception e) {
            return "异常: " + e.getMessage();
        }
    }

    /**
     * Ping服务器
     */
    public String pingServer() {
        try {
            String response = sendRequest("server.ping", mapper.createArrayNode());
            if (response != null && response.contains("result")) {
                return "成功";
            }
            return "失败";
        } catch (Exception e) {
            return "异常: " + e.getMessage();
        }
    }

    /**
     * 发送请求到Electrum服务器
     */
    private String sendRequest(String method, ArrayNode params) throws IOException {
        ObjectNode request = mapper.createObjectNode();
        request.put("id", requestId);
        request.put("method", method);
        request.set("params", params);
        request.put("jsonrpc", "2.0");

        String requestString = request.toString() + "\n";

        writer.write(requestString);
        writer.flush();

        String response = readResponse();
        requestId++;

        return response;
    }

    /**
     * 读取响应
     */
    private String readResponse() throws IOException {
        StringBuilder responseBuilder = new StringBuilder();
        char[] buffer = new char[1024];
        int bytesRead;
        long startTime = System.currentTimeMillis();

        while (System.currentTimeMillis() - startTime < 25000) {
            if (reader.ready()) {
                bytesRead = reader.read(buffer);
                if (bytesRead == -1) break;

                responseBuilder.append(buffer, 0, bytesRead);

                String currentResponse = responseBuilder.toString();
                if (currentResponse.trim().endsWith("}") && isValidJSON(currentResponse)) {
                    break;
                }
            } else {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        return responseBuilder.toString().trim();
    }

    /**
     * 验证JSON格式
     */
    private boolean isValidJSON(String json) {
        try {
            mapper.readTree(json);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public void disconnect() {
        try {
            if (reader != null) reader.close();
            if (writer != null) writer.close();
            if (socket != null) socket.close();
            System.out.println("连接已关闭");
        } catch (IOException e) {
            System.err.println("关闭连接时出错: " + e.getMessage());
        }
    }
}